FrameLib  0.1
Arbitrarily timed and sized frame-based DSP
FrameLib_Multichannel.h
Go to the documentation of this file.
1 
2 #ifndef FRAMELIB_MULTICHANNEL_H
3 #define FRAMELIB_MULTICHANNEL_H
4 
5 #include "FrameLib_Context.h"
6 #include "FrameLib_Object.h"
7 #include "FrameLib_DSP.h"
9 #include "FrameLib_Info.h"
10 #include <algorithm>
11 #include <vector>
12 
13 // FrameLib_MultiChannel
14 
15 // This abstract class allows mulitchannel connnections and the means to update the network according to the number of channels
16 
17 class FrameLib_MultiChannel : public FrameLib_Object<FrameLib_MultiChannel>, private FrameLib_ConnectionQueue::Item
18 {
19 
20 protected:
21 
22  // Connection Info Structure
23 
25  {
26  ConnectionInfo(FrameLib_Block *object = NULL, unsigned long idx = 0) : mObject(object), mIndex(idx) {}
27 
29  unsigned long mIndex;
30  };
31 
32 private:
33 
34  // IO Structures
35 
36  struct MultiChannelInput
37  {
38  MultiChannelInput() : mObject(NULL), mIndex(0) {}
39  MultiChannelInput(FrameLib_MultiChannel *object, unsigned long index) : mObject(object), mIndex(index) {}
40 
42  unsigned long mIndex;
43  };
44 
45  struct MultiChannelOutput
46  {
47  std::vector <ConnectionInfo> mConnections;
48  };
49 
50 public:
51 
52  // Constructors
53 
54  FrameLib_MultiChannel(ObjectType type, FrameLib_Context context, unsigned long nIns, unsigned long nOuts)
55  : FrameLib_Object(type), mQueue(context)
56  { setIO(nIns, nOuts); }
57 
58  FrameLib_MultiChannel(ObjectType type, FrameLib_Context context) : FrameLib_Object(type), mQueue(context) {}
59 
60  // Destructor
61 
63  {
64  mQueue.release();
66  }
67 
68  // Set Fixed Inputs
69 
70  virtual void setFixedInput(unsigned long idx, double *input, unsigned long size) {};
71 
72  // Audio Processing
73 
74  virtual void blockUpdate(double **ins, double **outs, unsigned long blockSize) {}
75  virtual void reset(double samplingRate, unsigned long maxBlockSize) {}
76 
77  static bool handlesAudio() { return false; }
78 
79  // Connection Methods
80 
81  // N.B. - No sanity checks here to maximise speed and help debugging (better for it to crash if a mistake is made)
82 
83  virtual void deleteConnection(unsigned long inIdx);
84  virtual void addConnection(FrameLib_MultiChannel *object, unsigned long outIdx, unsigned long inIdx);
85  virtual void clearConnections();
86  virtual bool isConnected(unsigned long inIdx);
87 
88 protected:
89 
90  // IO Utilities
91 
92  // Call this in derived class constructors if the IO size is not always the same
93 
94  void setIO(unsigned long nIns, unsigned long nOuts, unsigned long nAudioChans = 0)
95  {
96  FrameLib_Object::setIO(nIns, nOuts, nAudioChans);
97  mInputs.resize(getNumIns());
98  mOutputs.resize(getNumOuts());
99  }
100 
101  // Query Input Channels
102 
103  unsigned long getInputNumChans(unsigned long inIdx);
104  ConnectionInfo getInputChan(unsigned long inIdx, unsigned long chan) { return mInputs[inIdx].mObject->mOutputs[mInputs[inIdx].mIndex].mConnections[chan]; }
105 
106 private:
107 
108  // Deleted
109 
111  FrameLib_MultiChannel& operator=(const FrameLib_MultiChannel&);
112 
113  // Dependency Updating
114 
115  void addOutputDependency(FrameLib_MultiChannel *object);
116  std::vector <FrameLib_MultiChannel *>::iterator removeOutputDependency(FrameLib_MultiChannel *object);
117 
118  // Connection Methods (private)
119 
120  void updateConnections() { if (mQueue) mQueue->add(this); }
121 
122  void clearConnection(unsigned long inIdx);
123  void removeConnection(unsigned long inIdx);
124  std::vector <FrameLib_MultiChannel *>::iterator disconnect(FrameLib_MultiChannel *object);
125 
126  virtual void outputUpdate();
127 
128 protected:
129 
130  // Member Variables
131 
132  // Outputs
133 
134  std::vector <MultiChannelOutput> mOutputs;
135 
136 private:
137 
138  // Queue
139 
141 
142  // Connection Info
143 
144  std::vector <FrameLib_MultiChannel *> mOutputDependencies;
145  std::vector <MultiChannelInput> mInputs;
146 };
147 
148 // ************************************************************************************** //
149 
150 // FrameLib_Pack - Pack Multichannel Signals
151 
153 {
154  enum AtrributeList { kInputs };
155 
156  struct ParameterInfo : public FrameLib_Parameters::Info { ParameterInfo() { add("Sets the number of inputs."); } };
157 
158 public:
159 
160  FrameLib_Pack(FrameLib_Context context, FrameLib_Parameters::Serial *serialisedParameters, void *owner);
161 
162  // Info
163 
164  virtual std::string objectInfo(bool verbose);
165  virtual std::string inputInfo(unsigned long idx, bool verbose);
166  virtual std::string outputInfo(unsigned long idx, bool verbose);
167 
168  virtual const FrameLib_Parameters *getParameters() { return &mParameters; }
169 
170  virtual FrameType inputType(unsigned long idx) { return kFrameAny; }
171  virtual FrameType outputType(unsigned long idx) { return kFrameAny; }
172 
173 private:
174 
175  virtual bool inputUpdate();
176 
177  FrameLib_Parameters mParameters;
178 
179  static ParameterInfo sParamInfo;
180 };
181 
182 // ************************************************************************************** //
183 
184 // FrameLib_Unpack - Unpack Multichannel Signals
185 
187 {
188  enum AtrributeList { kOutputs };
189 
190  struct ParameterInfo : public FrameLib_Parameters::Info { ParameterInfo() { add("Sets the number of outputs."); } };
191 
192 public:
193 
194  FrameLib_Unpack(FrameLib_Context context, FrameLib_Parameters::Serial *serialisedParameters, void *owner);
195 
196  // Info
197 
198  virtual std::string objectInfo(bool verbose);
199  virtual std::string inputInfo(unsigned long idx, bool verbose);
200  virtual std::string outputInfo(unsigned long idx, bool verbose);
201 
202  virtual const FrameLib_Parameters *getParameters() { return &mParameters; }
203 
204  virtual FrameType inputType(unsigned long idx) { return kFrameAny; }
205  virtual FrameType outputType(unsigned long idx) { return kFrameAny; }
206 
207 private:
208 
209  virtual bool inputUpdate();
210 
211  FrameLib_Parameters mParameters;
212 
213  static ParameterInfo sParamInfo;
214 };
215 
216 // ************************************************************************************** //
217 
218 // FrameLib_Expand - MultiChannel expansion for FrameLib_Block objects
219 
220 template <class T> class FrameLib_Expand : public FrameLib_MultiChannel
221 {
222 
223 public:
224 
225  FrameLib_Expand(FrameLib_Context context, FrameLib_Parameters::Serial *serialisedParameters, void *owner)
226  : FrameLib_MultiChannel(T::getType(), context), mContext(context), mAllocator(context), mSerialisedParameters(serialisedParameters->size()), mOwner(owner)
227  {
228  // Make first block
229 
230  mBlocks.push_back(new T(context, serialisedParameters, owner));
231 
232  // Copy serialised parameters for later instantiations
233 
234  mSerialisedParameters.write(serialisedParameters);
235 
236  // Set up IO / fixed inputs / audio temps
237 
238  setIO(mBlocks[0]->getNumIns(), mBlocks[0]->getNumOuts(), mBlocks[0]->getNumAudioChans());
239  mFixedInputs.resize(getNumIns());
240  mAudioTemps.resize(getNumAudioOuts());
241 
242  // Make initial output connections
243 
244  for (unsigned long i = 0; i < getNumOuts(); i++)
245  mOutputs[i].mConnections.push_back(ConnectionInfo(mBlocks[0], i));
246 
247  reset(0.0, 4096);
248  }
249 
251  {
252  // Clear connections before deleting internal objects
253 
255 
256  // Delete blocks
257 
258  for (std::vector <FrameLib_Block *> :: iterator it = mBlocks.begin(); it != mBlocks.end(); it++)
259  delete(*it);
260  }
261 
262  // Fixed Inputs
263 
264  virtual void setFixedInput(unsigned long idx, double *input, unsigned long size)
265  {
266  if (idx < mFixedInputs.size())
267  {
268  mFixedInputs[idx].assign(input, input + size);
269  updateFixedInput(idx);
270  }
271  }
272 
273  // Audio Processing
274 
275  // FIX - allow the expand object to write/read different blocks from different audio IO (auto multichannel)
276 
277  virtual void blockUpdate(double **ins, double **outs, unsigned long blockSize)
278  {
279  // Allocate temporary memory
280 
281  if (getNumAudioOuts())
282  mAudioTemps[0] = (double *) mAllocator->alloc(sizeof(double) * blockSize * getNumAudioOuts());
283  for (unsigned long i = 1; i < getNumAudioOuts(); i++)
284  mAudioTemps[i] = mAudioTemps[0] + (i * blockSize);
285 
286  // Zero outputs
287 
288  for (unsigned long i = 0; i < getNumAudioOuts(); i++)
289  std::fill_n(outs[i], blockSize, 0.0);
290 
291  // Process and sum to outputs
292 
293  for (std::vector <FrameLib_Block *> :: iterator it = mBlocks.begin(); it != mBlocks.end(); it++)
294  {
295  (*it)->blockUpdate(ins, &mAudioTemps[0], blockSize);
296 
297  for (unsigned long i = 0; i < getNumAudioOuts(); i++)
298  for (unsigned long j = 0; j < blockSize; j++)
299  outs[i][j] += mAudioTemps[i][j];
300  }
301 
302  // Release temporary memory and clear allocator
303 
304  if (getNumAudioOuts())
305  mAllocator->dealloc(mAudioTemps[0]);
306 
307  mAllocator->clear();
308  }
309 
310  // Reset
311 
312  virtual void reset(double samplingRate, unsigned long maxBlockSize)
313  {
314  mSamplingRate = samplingRate;
315  mMaxBlockSize = maxBlockSize;
316 
317  for (std::vector <FrameLib_Block *> :: iterator it = mBlocks.begin(); it != mBlocks.end(); it++)
318  (*it)->reset(samplingRate, maxBlockSize);
319  }
320 
321  // Handles Audio
322 
323  static bool handlesAudio() { return T::handlesAudio(); }
324 
325  virtual std::string objectInfo(bool verbose) { return mBlocks[0]->objectInfo(verbose); }
326  virtual std::string inputInfo(unsigned long idx, bool verbose) { return mBlocks[0]->inputInfo(idx, verbose); }
327  virtual std::string outputInfo(unsigned long idx, bool verbose) { return mBlocks[0]->outputInfo(idx, verbose); }
328  virtual std::string audioInfo(unsigned long idx, bool verbose) { return mBlocks[0]->audioInfo(idx, verbose); }
329 
330  virtual FrameType inputType(unsigned long idx) { return mBlocks[0]->inputType(idx); }
331  virtual FrameType outputType(unsigned long idx) { return mBlocks[0]->outputType(idx); }
332 
333  virtual const FrameLib_Parameters *getParameters() { return mBlocks[0]->getParameters(); }
334 
335 private:
336 
337  // Update Fixed Inputs
338 
339  void updateFixedInput(unsigned long idx)
340  {
341  for (unsigned long i = 0; i < mBlocks.size(); i++)
342  mBlocks[i]->setFixedInput(idx, &mFixedInputs[idx][0], mFixedInputs[idx].size());
343  }
344 
345  // Update (expand)
346 
347  virtual bool inputUpdate()
348  {
349  // Find number of channels (always keep at least one channel)
350 
351  unsigned long nChannels = 1;
352  unsigned long cChannels = mBlocks.size();
353 
354  for (unsigned long i = 0; i < getNumIns(); i++)
355  if (getInputNumChans(i) > nChannels)
356  nChannels = getInputNumChans(i);
357 
358  // Resize if necessary
359 
360  bool numChansChanged = nChannels != cChannels;
361 
362  if (numChansChanged)
363  {
364  if (nChannels > cChannels)
365  {
366  mBlocks.resize(nChannels);
367 
368  for (unsigned long i = cChannels; i < nChannels; i++)
369  {
370  mBlocks[i] = new T(mContext, &mSerialisedParameters, mOwner);
371  mBlocks[i]->reset(mSamplingRate, mMaxBlockSize);
372  }
373  }
374  else
375  {
376  for (unsigned long i = nChannels; i < cChannels; i++)
377  delete mBlocks[i];
378 
379  mBlocks.resize(nChannels);
380  }
381 
382  // Redo output connection lists
383 
384  for (unsigned long i = 0; i < getNumOuts(); i++)
385  mOutputs[i].mConnections.clear();
386 
387  for (unsigned long i = 0; i < getNumOuts(); i++)
388  for (unsigned long j = 0; j < nChannels; j++)
389  mOutputs[i].mConnections.push_back(ConnectionInfo(mBlocks[j], i));
390 
391  // Update Fixed Inputs
392 
393  for (unsigned long i = 0; i < getNumIns(); i++)
394  updateFixedInput(i);
395  }
396 
397  // Make input connections
398 
399  for (unsigned long i = 0; i < getNumIns(); i++)
400  {
401  if (getInputNumChans(i))
402  {
403  for (unsigned long j = 0; j < nChannels; j++)
404  {
405  ConnectionInfo connection = getInputChan(i, j % getInputNumChans(i));
406  mBlocks[j]->addConnection(connection.mObject, connection.mIndex, i);
407  }
408  }
409  else
410  {
411  for (unsigned long j = 0; j < nChannels; j++)
412  mBlocks[j]->deleteConnection(i);
413  }
414  }
415 
416  return numChansChanged;
417  }
418 
419  // Member Variables
420 
421  FrameLib_Context mContext;
422  FrameLib_Context::Allocator mAllocator;
423  FrameLib_Parameters::AutoSerial mSerialisedParameters;
424 
425  std::vector <FrameLib_Block *> mBlocks;
426  std::vector <std::vector <double> > mFixedInputs;
427 
428  void *mOwner;
429 
430  unsigned long mMaxBlockSize;
431  double mSamplingRate;
432 
433  std::vector<double *> mAudioTemps;
434 };
435 
436 #endif
ObjectType
Definition: FrameLib_Types.h:24
virtual std::string objectInfo(bool verbose=false)
Definition: FrameLib_Object.h:68
virtual FrameType outputType(unsigned long idx)
Definition: FrameLib_Multichannel.h:331
Definition: FrameLib_Multichannel.h:152
unsigned long getInputNumChans(unsigned long inIdx)
Definition: FrameLib_Multichannel.cpp:52
Definition: FrameLib_Parameters.h:21
unsigned long getNumIns()
Definition: FrameLib_Object.h:38
virtual void reset(double samplingRate, unsigned long maxBlockSize)
Definition: FrameLib_Multichannel.h:312
void setIO(unsigned long nIns, unsigned long nOuts, unsigned long nAudioChans=0)
Definition: FrameLib_Multichannel.h:94
virtual FrameType outputType(unsigned long idx)
Definition: FrameLib_Multichannel.h:171
Definition: FrameLib_Context.h:10
virtual FrameType inputType(unsigned long idx)
Definition: FrameLib_Multichannel.h:330
static bool handlesAudio()
Definition: FrameLib_Multichannel.h:77
virtual void addConnection(FrameLib_MultiChannel *object, unsigned long outIdx, unsigned long inIdx)
Definition: FrameLib_Multichannel.cpp:14
static bool handlesAudio()
Definition: FrameLib_Multichannel.h:323
Definition: FrameLib_Parameters.h:34
virtual std::string outputInfo(unsigned long idx, bool verbose)
Definition: FrameLib_Multichannel.h:327
virtual const FrameLib_Parameters * getParameters()
Definition: FrameLib_Multichannel.h:168
ManagedPointer< FrameLib_ConnectionQueue, &Global::getConnectionQueue, &Global::releaseConnectionQueue > ConnectionQueue
Definition: FrameLib_Context.h:72
virtual std::string objectInfo(bool verbose)
Definition: FrameLib_Multichannel.h:325
virtual void blockUpdate(double **ins, double **outs, unsigned long blockSize)
Definition: FrameLib_Multichannel.h:74
virtual std::string outputInfo(unsigned long idx, bool verbose=false)
Definition: FrameLib_Object.h:70
virtual FrameType inputType(unsigned long idx)
Definition: FrameLib_Multichannel.h:170
Definition: FrameLib_Object.h:15
virtual bool isConnected(unsigned long inIdx)
Definition: FrameLib_Multichannel.cpp:47
virtual FrameType inputType(unsigned long idx)
Definition: FrameLib_Multichannel.h:204
Definition: FrameLib_Multichannel.h:24
virtual std::string audioInfo(unsigned long idx, bool verbose)
Definition: FrameLib_Multichannel.h:328
Definition: FrameLib_Multichannel.h:17
unsigned long getNumAudioOuts()
Definition: FrameLib_Object.h:41
virtual std::string inputInfo(unsigned long idx, bool verbose=false)
Definition: FrameLib_Object.h:69
ObjectType getType()
Definition: FrameLib_Object.h:27
Definition: FrameLib_ConnectionQueue.h:11
Definition: FrameLib_Multichannel.h:220
ConnectionInfo(FrameLib_Block *object=NULL, unsigned long idx=0)
Definition: FrameLib_Multichannel.h:26
virtual void setFixedInput(unsigned long idx, double *input, unsigned long size)
Definition: FrameLib_Multichannel.h:264
virtual const FrameLib_Parameters * getParameters()
Definition: FrameLib_Multichannel.h:202
virtual void blockUpdate(double **ins, double **outs, unsigned long blockSize)
Definition: FrameLib_Multichannel.h:277
FrameLib_Expand(FrameLib_Context context, FrameLib_Parameters::Serial *serialisedParameters, void *owner)
Definition: FrameLib_Multichannel.h:225
Definition: FrameLib_Object.h:95
FrameLib_Block * mObject
Definition: FrameLib_Multichannel.h:28
size_t blockSize(void *ptr)
Definition: FrameLib_Memory.cpp:23
Definition: FrameLib_Parameters.h:153
virtual std::string inputInfo(unsigned long idx, bool verbose)
Definition: FrameLib_Multichannel.h:326
virtual void deleteConnection(unsigned long inIdx)
Definition: FrameLib_Multichannel.cpp:8
virtual ~FrameLib_MultiChannel()
Definition: FrameLib_Multichannel.h:62
Definition: FrameLib_Types.h:25
void setIO(unsigned long nIns, unsigned long nOuts, unsigned long nAudioChans=0)
Definition: FrameLib_Object.h:31
virtual FrameType outputType(unsigned long idx)
Definition: FrameLib_Multichannel.h:205
std::vector< MultiChannelOutput > mOutputs
Definition: FrameLib_Multichannel.h:134
ConnectionInfo getInputChan(unsigned long inIdx, unsigned long chan)
Definition: FrameLib_Multichannel.h:104
unsigned long getNumOuts()
Definition: FrameLib_Object.h:39
virtual void clearConnections()
Definition: FrameLib_Multichannel.cpp:30
Definition: FrameLib_Parameters.h:129
unsigned long mIndex
Definition: FrameLib_Multichannel.h:29
FrameType
Definition: FrameLib_Types.h:25
Definition: FrameLib_Multichannel.h:186
FrameLib_MultiChannel(ObjectType type, FrameLib_Context context, unsigned long nIns, unsigned long nOuts)
Definition: FrameLib_Multichannel.h:54
ManagedPointer< FrameLib_LocalAllocator, &Global::getAllocator, &Global::releaseAllocator > Allocator
Definition: FrameLib_Context.h:71
virtual void setFixedInput(unsigned long idx, double *input, unsigned long size)
Definition: FrameLib_Multichannel.h:70
unsigned long getNumAudioChans()
Definition: FrameLib_Object.h:42
virtual void reset(double samplingRate, unsigned long maxBlockSize)
Definition: FrameLib_Multichannel.h:75
virtual const FrameLib_Parameters * getParameters()
Definition: FrameLib_Multichannel.h:333
FrameLib_MultiChannel(ObjectType type, FrameLib_Context context)
Definition: FrameLib_Multichannel.h:58
~FrameLib_Expand()
Definition: FrameLib_Multichannel.h:250